package com.youlai.system.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.NumberUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.youlai.system.common.base.BaseQuery;
import com.youlai.system.common.base.IBaseEnum;
import com.youlai.system.common.enums.GenderEnum;
import com.youlai.system.common.enums.StatusEnum;
import com.youlai.system.model.entity.*;
import com.youlai.system.model.query.ExamPageQuery;
import com.youlai.system.model.query.UserBusinessQuery;
import com.youlai.system.model.vo.*;
import com.youlai.system.service.*;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 首页业务处理实现
 */
@Service
@RequiredArgsConstructor
public class DashBoardServiceImpl implements DashBoardService {

    /**
     * 部门服务
     */
    private final SysDeptService deptService;

    /**
     * 用户角色服务
     */
    private final SysUserRoleService userRoleService;

    /**
     * 角色服务
     */
    private final SysRoleService roleService;

    /**
     * 故障分类服务
     */
    private final SysCategoryService categoryService;

    /**
     * 故障科目服务
     */
    private final SysCourseService courseService;

    /**
     * 成绩服务
     */
    private final SysScoreService scoreService;

    /**
     * 用户服务
     */
    private final SysUserService userService;

    /**
     * 问题分类服务
     */
    private final SysQuestionService questionService;

    /**
     * 培训地点服务
     */
    private final SysLocationService locationService;

    /**
     * 整改措施服务
     */
    private final SysMeasureService measureService;

    /**
     * 考试管理
     */
    private final SysExamService examService;

    @Override
    public DashBoardCountVO loadAllCountData(BaseQuery baseQuery) {
        DashBoardCountVO dashBoardCountVO = new DashBoardCountVO();

        //部门情况
        Long lineCount = deptService.lineCount();
        Long carCount = deptService.carCount();
        dashBoardCountVO.setDeptLineCount(lineCount);
        dashBoardCountVO.setDeptCarCount(carCount);

        //员工情况
        SysRole teacherRole = roleService.getTeacherRole();
        SysRole studentRole = roleService.getStudentRole();
        if (teacherRole != null) {
            Long teacherCount = userRoleService.roleUserCount(teacherRole.getId());
            dashBoardCountVO.setTeacherCount(teacherCount);
        }
        if (studentRole != null) {
            Long studentCount = userRoleService.roleUserCount(studentRole.getId());
            dashBoardCountVO.setStudentCount(studentCount);
        }

        //管培情况
        Long categoryCount = categoryService.count();
        Long courseCount = courseService.count();
        dashBoardCountVO.setCategoryCount(categoryCount);
        dashBoardCountVO.setCourseCount(courseCount);

        //成绩情况
        LambdaQueryWrapper<SysScore> queryWrapper = new LambdaQueryWrapper<>();
        if (baseQuery.getLoginUserId() != null) {
            queryWrapper.eq(SysScore::getStudentId, baseQuery.getLoginUserId());
        }
        Long scoreTotalCount = scoreService.count(queryWrapper);
        Long scorePassCount = scoreService.scorePassCount(baseQuery);
        dashBoardCountVO.setScoreTotalCount(scoreTotalCount);
        dashBoardCountVO.setScorePassCount(scorePassCount);

        Long deptCount = deptService.count();
        dashBoardCountVO.setDeptCount(deptCount);

        Long userCount = userService.count();
        dashBoardCountVO.setUserCount(userCount);
        if (dashBoardCountVO.getScoreTotalCount() != 0L) {
            String passRate = NumberUtil.decimalFormat("#.##", dashBoardCountVO.getScorePassCount().doubleValue() * 100 / dashBoardCountVO.getScoreTotalCount().doubleValue());
            dashBoardCountVO.setPassRate(Double.valueOf(passRate));
        } else {
            dashBoardCountVO.setPassRate(0D);
        }

        return dashBoardCountVO;
    }

    @Override
    public List<QuestionScoreCountVO> loadQuestionCountData(BaseQuery baseQuery) {

        List<QuestionScoreCountVO> questionScoreCountVOList = scoreService.getAllQuestionScoreCountList(baseQuery);
        List<Long> questionIdList = questionScoreCountVOList.stream().map(QuestionScoreCountVO::getQuestionId).collect(Collectors.toList());
        if (CollectionUtil.isNotEmpty(questionIdList)) {
            List<SysQuestion> questionList = questionService.listByIds(questionIdList);
            Map<Long, String> questionNameMap = questionList.stream().collect(Collectors.toMap(SysQuestion::getId, SysQuestion::getContent));
            questionScoreCountVOList.forEach(questionScoreCountVO -> {
                String questionName = questionNameMap.get(questionScoreCountVO.getQuestionId());
                questionScoreCountVO.setQuestionName(questionName);
            });
        }

        return questionScoreCountVOList;
    }

    @Override
    public List<LocationScoreCountVO> loadLocationCountData(BaseQuery baseQuery) {
        List<LocationScoreCountVO> locationScoreCountVOList = scoreService.getAllLocationScoreCountList(baseQuery);
        List<Long> locationIdList = locationScoreCountVOList.stream().map(LocationScoreCountVO::getLocationId).collect(Collectors.toList());
        if (CollectionUtil.isNotEmpty(locationIdList)) {
            List<SysLocation> locationList = locationService.listByIds(locationIdList);
            Map<Long, String> locationNameMap = locationList.stream().collect(Collectors.toMap(SysLocation::getId, SysLocation::getContent));
            locationScoreCountVOList.forEach(locationScoreCountVO -> {
                String locationName = locationNameMap.get(locationScoreCountVO.getLocationId());
                locationScoreCountVO.setLocationName(locationName);
            });
        }

        return locationScoreCountVOList;
    }

    @Override
    public List<MeasureScoreCountVO> loadMeasureCountData(BaseQuery baseQuery) {
        List<MeasureScoreCountVO> measureScoreCountVOList = scoreService.getAllMeasureScoreCountList(baseQuery);
        List<Long> measureIdList = measureScoreCountVOList.stream().map(MeasureScoreCountVO::getMeasureId).collect(Collectors.toList());
        if (CollectionUtil.isNotEmpty(measureIdList)) {
            List<SysMeasure> measureList = measureService.listByIds(measureIdList);
            Map<Long, String> measureNameMap = measureList.stream().collect(Collectors.toMap(SysMeasure::getId, SysMeasure::getContent));
            measureScoreCountVOList.forEach(measureScoreCountVO -> {
                String measureName = measureNameMap.get(measureScoreCountVO.getMeasureId());
                measureScoreCountVO.setMeasureName(measureName);
            });
        }

        return measureScoreCountVOList;
    }

    @Override
    public List<CourseScoreCountVO> loadCourseCountData(BaseQuery baseQuery) {
        List<CourseScoreCountVO> courseScoreCountVOList = scoreService.getAllCourseScoreCountList(baseQuery);
        List<Long> couresIdList = courseScoreCountVOList.stream().map(CourseScoreCountVO::getCourseId).collect(Collectors.toList());
        if (CollectionUtil.isNotEmpty(couresIdList)) {
            List<SysCourse> courseList = courseService.listByIds(couresIdList);
            Map<Long, String> courseNameMap = courseList.stream().collect(Collectors.toMap(SysCourse::getId, SysCourse::getContent));
            courseScoreCountVOList.forEach(courseScoreCountVO -> {
                String courseName = courseNameMap.get(courseScoreCountVO.getCourseId());
                courseScoreCountVO.setCourseName(courseName);
            });
        }

        return courseScoreCountVOList;
    }

    @Override
    public List<DeptDegreeCountVO> loadDeptDegreeCountData() {
        List<DeptDegreeCountVO> deptDegreeCountVOList = examService.getDeptDegreeCountList();
        return deptDegreeCountVOList;
    }

    @Override
    public List<DegreeCountVO> loadDegreeCountData(BaseQuery baseQuery) {
        List<DegreeCountVO> degreeCountVOList = examService.getAllDegreeContList(baseQuery);
        return degreeCountVOList;
    }

    @Override
    public UserBusinessCard getUserBusinessCard(UserBusinessQuery query) {
        UserBusinessCard userBusinessCard = userService.getUserBusinessCard(query.getUserId());
        userBusinessCard.setStatusLabel(IBaseEnum.getLabelByValue(userBusinessCard.getStatus(), StatusEnum.class));
        userBusinessCard.setSexLabel(IBaseEnum.getLabelByValue(userBusinessCard.getSex(), GenderEnum.class));
        ExamPageQuery examPageQuery = new ExamPageQuery();
        examPageQuery.setUserId(query.getUserId());
        userBusinessCard.setExamList(examService.getExamList(examPageQuery));
        return userBusinessCard;
    }
}
